#ifdef CHANGED

#include "copyright.h"
#include "system.h"
#include "userthread.h"
#include "addrspace.h"

void IniReg(int f,int arg){

  machine->WriteRegister (PCReg, f);
  machine->WriteRegister (4, arg);
  machine->WriteRegister (NextPCReg, f+4);
  machine->WriteRegister (StackReg, machine->ReadRegister(StackReg)-currentThread->getStackAddr()*3* PageSize);
  DEBUG ('a', "Initializing stack register to %d\n",
	 machine->ReadRegister(StackReg)- currentThread->getStackAddr()*3* PageSize);

}

static void StartUserThread(int f){
  UserThreadParam *param=(UserThreadParam *) f;
  currentThread->space->InitRegisters();
  IniReg(param->f,param->arg);
  machine->Run();
  ASSERT(FALSE);	
}

int do_UserThreadCreate(int f, int arg) {
 
  int i;
  if((i=currentThread->space->allocStack())==-1){
	return -1;
  }

  Thread *newThread = new Thread ("newThread");
  newThread->setStackAddr(i);
  newThread->setTid(currentThread->space->getnumTotalThread()+1);
  currentThread->space->setnumCurrentThread(currentThread->space->getnumCurrentThread()+1);
  currentThread->space->insertThread(newThread->getTid());
  currentThread->space->setnumTotalThread(currentThread->space->getnumTotalThread()+1);
  UserThreadParam *param=new UserThreadParam;
  param->f=f;
  param->arg=arg;
  newThread->space=currentThread->space;
  newThread->Fork (StartUserThread, (int) param);
  return newThread->getTid();
  
}

void do_UserThreadExit() {
  int i=currentThread->getStackAddr();
  currentThread->space->freeStack(i);
  if(currentThread->space->getnumCurrentThread()==1){
	interrupt->Halt();
  }
  else{
	currentThread->space->setnumCurrentThread(currentThread->space->getnumCurrentThread()-1);
	currentThread->space->deletedThread(currentThread->getTid());
	if(currentThread->space->getnumCurrentThread()==0){
		delete currentThread->space;
	}
	currentThread->Finish();
  }
}

#endif //CHANGED
